package com.kcyu.sfhinvoice.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kcyu.sfhinvoice.config.MyException;
import com.kcyu.sfhinvoice.domain.User;
import com.kcyu.sfhinvoice.dto.ChangePasswordDTO;
import com.kcyu.sfhinvoice.dto.LoginDTO;
import com.kcyu.sfhinvoice.enums.UserStatusEnums;
import com.kcyu.sfhinvoice.service.NotificationService;
import com.kcyu.sfhinvoice.service.UserService;
import com.kcyu.sfhinvoice.mapper.UserMapper;
import com.kcyu.sfhinvoice.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import springfox.documentation.builders.ValidationResult;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
* @author yujiancong
* @description 针对表【user】的数据库操作Service实现
* @createDate 2024-01-02 10:54:18
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private NotificationService notificationService;

    @Override
    public User login(LoginDTO loginDTO) {
        // 写死一个管理员登录的账号
        if(loginDTO.getUsername().equals("kcyu") && loginDTO.getPassword().equals("4404050")) {
            return getDevelopUser();
        }


        // 检查是否已经连续输错密码导致暂时冻结
        Integer count = (Integer) redisUtils.get("sfh-invoice:login-cache:" + loginDTO.getUsername());
        if(count != null && count >= 3) {
            long unfreezeTime = (long) redisUtils.get("sfh-invoice:login-lock-time:" + loginDTO.getUsername());
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = dateFormat.format(new Date(unfreezeTime));
            throw new MyException("由于你已经连续输错密码3次，请" + format + "后重试");
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUsername, loginDTO.getUsername());
        User user = this.getOne(queryWrapper);
        if(user != null) {
            if(user.getPassword().equals(loginDTO.getPassword())) {

//                if(user.getStatus().equals("REGISTER")) {
//                    throw new MyException("用户已完成注册，请联系管理员审核");
//                }

                redisUtils.del("sfh-invoice:login-cache:" + loginDTO.getUsername());
                StpUtil.login(user.getId());
                user.setLastLoginTime(new Date());
                this.updateById(user);
                user.setPassword(null);
                notificationService.loginNotice();
                return user;
            } else {
                // 存入缓存，记录登录，防止撞库攻击
                if(count == null) {
                    count = 1;
                    redisUtils.set("sfh-invoice:login-cache:" + loginDTO.getUsername(), 1, 600);
                } else {
                    redisUtils.set("sfh-invoice:login-cache:" + loginDTO.getUsername(), ++count, 600);
                }
                log.info("该账号登录失败次数：{}", count);
                if(count >= 3) {
                    redisUtils.set("sfh-invoice:login-lock-time:" + loginDTO.getUsername(), new Date().getTime() + (600 * 1000), 600);
                    throw new MyException("密码输入错误次数过多，请10分钟后重试");
                }
                throw new MyException("密码错误，已累计错误" + count + "次，错误三次后将锁定10分钟");
            }
        } else {
            throw new MyException("用户不存在");
        }
    }

    @Override
    public User addUser(User user) {
        if(this.getOne(new QueryWrapper<User>().lambda().eq(User::getUsername, user.getUsername())) != null) {
            throw new MyException("用户名已存在");
        }
        user.setPassword("123456");
        user.setStatus(UserStatusEnums.INIT);
        boolean b = this.save(user);
        if(b) {
            return user;
        } else {
            throw new MyException("添加失败");
        }
    }

    @Override
    public boolean resetPassword(String id) {
        User one = this.getById(id);
        if(one != null) {
            one.setPassword("123456");
            one.setStatus(UserStatusEnums.INIT);
            return this.updateById(one);
        } else {
            throw new MyException("用户不存在");
        }
    }

    @Override
    public boolean register(User user) {
        // 检测是否重复用户名
        if(this.getOne(new QueryWrapper<User>().lambda().eq(User::getUsername, user.getUsername())) != null) {
            throw new MyException("用户名已存在");
        }
        user.setRole("开票员");
        user.setStatus(UserStatusEnums.WAIT);
        return this.save(user);
    }

    @Override
    public boolean changePassword(ChangePasswordDTO changePasswordDTO) {
        int loginIdAsInt = StpUtil.getLoginIdAsInt();
        User user = this.getById(loginIdAsInt);
        if(user.getPassword().equals(changePasswordDTO.getOldPassword())) {
            user.setPassword(changePasswordDTO.getNewPassword());
            return this.updateById(user);
        } else {
            throw new MyException("原密码错误");
        }
    }

    @Override
    public User getDevelopUser() {
        User user = new User();
        user.setUsername("kcyu");
        user.setRole("管理员");
        user.setId(999);
        user.setStatus(UserStatusEnums.NORMAL);
        StpUtil.login(user.getId());
        return user;
    }
}




